home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 11.3 KB | 559 lines | [TEXT/CWIE] |
- /*
- Random and sundry error, file and path name utilities
-
- Created 29 Jan 1996 by EGH
-
- Copyright © 1996, Apple Computer, Inc. All rights reserved.
- */
-
- #include <FixMath.h>
- #include <fp.h>
-
- #include <stdio.h>
- #include <String_Utils.h>
-
- #include "CApp.h"
-
- #include "CUtils.h"
-
- /* GetFullPathName
-
- Get the full path name of the passed file, but force its length to fit into maxSize.
- It is obviously more desirable to not restrict its length, but in this case we desire
- this and "elipsize" the string by removing characters from the center.
- */
- void GetFullPathName(
- const FSSpec *fileSpec,
- Str255 outPathName,
- short maxSize)
- {
- // force an upper limit to what will fit in a Str255
- if (maxSize > sizeof (Str255) - 1)
- maxSize = sizeof (Str255) - 1;
-
- Int16 pathLen;
- Handle pathH;
- OSErr err = FSpGetFullPath(fileSpec, &pathLen, &pathH);
- if (err == noErr)
- {
- ElipsedPathNameH(pathH, maxSize, outPathName, '…');
- ::DisposeHandle(pathH);
- }
- else
- {
- // no memory (?!) so just copy the file's name
- CopyPStr(fileSpec->name, outPathName);
- }
- }
-
- /* FSpGetFullPath
-
- Grok the full the path name of the passed file.
- Nabbed from More Files 1.4.1 from my colleagues at Apple Developer Technical Support.
- */
- OSErr FSpGetFullPath(
- const FSSpec *spec,
- short *fullPathLength,
- Handle *fullPath)
- {
- OSErr result;
- FSSpec tempSpec;
- CInfoPBRec pb;
-
- /* Make a copy of the input FSSpec that can be modified */
- BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
-
- if ( tempSpec.parID == fsRtParID )
- {
- /* The object is a volume */
-
- /* Add a colon to make it a full pathname */
- ++tempSpec.name[0];
- tempSpec.name[tempSpec.name[0]] = ':';
-
- /* We're done */
- result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
- }
- else
- {
- /* The object isn't a volume */
-
- /* Put the object name in first */
- result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
- if ( result == noErr )
- {
- /* Get the ancestor directory names */
- pb.dirInfo.ioNamePtr = tempSpec.name;
- pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
- pb.dirInfo.ioDrParID = tempSpec.parID;
- do /* loop until we have an error or find the root directory */
- {
- pb.dirInfo.ioFDirIndex = -1;
- pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
- result = PBGetCatInfoSync(&pb);
- if ( result == noErr )
- {
- /* Append colon to directory name */
- ++tempSpec.name[0];
- tempSpec.name[tempSpec.name[0]] = ':';
-
- /* Add directory name to beginning of fullPath */
- (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]);
- result = MemError();
- }
- } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) );
- }
- }
- if ( result == noErr )
- {
- /* Return the length */
- *fullPathLength = GetHandleSize(*fullPath);
- }
- else
- {
- /* Dispose of the handle and return NULL and zero length */
- DisposeHandle(*fullPath);
- *fullPath = NULL;
- *fullPathLength = 0;
- }
-
- return result;
- }
-
-
- /* ElipsedPathNameH
-
- Gracefully degrade the passed string by removing characters from the center
- until it fits into the passed maximum width. Inserts an elipsis character to indicate this.
- */
- void ElipsedPathNameH(
- Handle pathNameH,
- short maxWidth,
- Str255 elipsedName,
- char elipsis)
- {
- long pNameLen = GetHandleSize(pathNameH);
- char saveState = HGetState(pathNameH);
- Ptr pathNameP = *pathNameH;
-
- HLock(pathNameH);
-
- if ((pNameLen <= 255) && (TextWidth(pathNameP, 0, (short)pNameLen) <= maxWidth))
- {
- BlockMove(pathNameP, (Ptr)(elipsedName + 1), pNameLen);
- *elipsedName = (char)pNameLen;
- }
- else
- {
- long i, j, width = CharWidth(elipsis);
- char rightChars[128];
-
- maxWidth /= 2;
-
- for (i = 1; (i < pNameLen) && (i < 128); i++)
- {
- char nextChar = pathNameP[i - 1];
-
- width += CharWidth(nextChar);
- if (width >= maxWidth) break;
- elipsedName[i] = nextChar;
- }
-
- width = 0;
- for (j = pNameLen - 1, *rightChars = 0; (j > i) && (*rightChars < 128); j--)
- {
- char nextChar = pathNameP[j];
-
- width += CharWidth(nextChar);
- if (width >= maxWidth) break;
- rightChars[++*rightChars] = nextChar;
- }
-
- elipsedName[(*elipsedName = (char)i)] = elipsis;
-
- while (*rightChars)
- {
- elipsedName[++*elipsedName] = rightChars[(*rightChars)--];
- }
- }
-
- HSetState(pathNameH, saveState);
- }
-
-
- /* ElipsedPathName
-
- Same as ElipsedPathNameH except uses Str255's rather than a handle.
- */
- void ElipsedPathName(
- Str255 pathName,
- short maxWidth,
- Str255 elipsedName,
- char elipsis)
- {
- Int16 pNameLen = pathName[0];
- UInt8 *pathNameP = &pathName[1];
- Int16 textWidth;
-
- textWidth = ::StringWidth(pathName);
- if ((pNameLen <= 255) && (textWidth <= maxWidth))
- {
- BlockMove(pathNameP, (Ptr)(elipsedName + 1), pNameLen);
- *elipsedName = (char)pNameLen;
- }
- else
- {
- long i, j, width = CharWidth(elipsis);
- char rightChars[128];
-
- maxWidth /= 2;
-
- for (i = 1; (i < pNameLen) && (i < 128); i++)
- {
- char nextChar = pathNameP[i - 1];
-
- width += CharWidth(nextChar);
- if (width >= maxWidth) break;
- elipsedName[i] = nextChar;
- }
-
- width = 0;
- for (j = pNameLen - 1, *rightChars = 0; (j > i) && (*rightChars < 128); j--)
- {
- char nextChar = pathNameP[j];
-
- width += CharWidth(nextChar);
- if (width >= maxWidth) break;
- rightChars[++*rightChars] = nextChar;
- }
-
- elipsedName[(*elipsedName = (char)i)] = elipsis;
-
- while (*rightChars)
- {
- elipsedName[++*elipsedName] = rightChars[(*rightChars)--];
- }
- }
- }
-
-
- /* SetSizedDescriptor
-
- Set the descriptor of the passed pane, but gracefully degrade the
- length of the string to physically fit into the pane's frame.
- */
- void SetSizedDescriptor(
- LWindow *parent,
- PaneIDT inPaneID,
- StringPtr inDescStr)
- {
- LCaption *pane = (LCaption *)parent->FindPaneByID(inPaneID);
- pane->FocusDraw(); // just to be in a valid port
- ResIDT texttraitsID = pane->GetTextTraitsID();
- UTextTraits::SetPortTextTraits(texttraitsID);
- SDimension16 panesize;
- pane->GetFrameSize(panesize);
- Str255 elipStr;
- ::ElipsedPathName(inDescStr, panesize.width, elipStr, '…');
- pane->SetDescriptor(elipStr);
- }
-
-
- /* ReportError
-
- Report an error to the user.
- */
- void ReportError(
- ExceptionCode inErr,
- Int16 inStrIndex)
- {
- Str255
- errStr = "\pAn error occurred.",
- errNumStr,
- errDescStr;
- Int16 descIndex;
-
- gApp->BugUserTilSwitchedIn();
-
- // make some attempt to provide a description of the error
- switch (inErr)
- {
- case iMemFullErr:
- descIndex = err_NotEnufMemory;
- break;
-
- case notEnoughMemoryErr:
- descIndex = err_NotEnufPhysicalMemory;
- break;
-
- case dirFulErr:
- case dskFulErr:
- descIndex = err_DiskFull;
- break;
-
- case ioErr:
- case fnOpnErr:
- case eofErr:
- case fnfErr:
- case nsvErr:
- descIndex = err_DiskError;
- break;
-
- case resNotFound:
- descIndex = err_NoResource;
-
- default:
- descIndex = err_NoDescription;
- }
- ::GetIndString(errDescStr, STRx_ErrorDescs, descIndex);
-
- ::SetCursor(&qd.arrow);
-
- ::GetIndString(errStr, STRx_Errors, inStrIndex);
- ::NumToString(inErr, errNumStr);
- ::ParamText(errStr, errNumStr, errDescStr, "\p");
- ::StopAlert(ALRT_Error, nil);
- }
-
-
- OSErr GetFileParent(
- FSSpec *fileSpec,
- FSSpec *parentSpec)
- {
- CInfoPBRec pBlock;
- OSErr result;
-
- pBlock.dirInfo.ioVRefNum = fileSpec-> vRefNum;
- pBlock.dirInfo.ioDrDirID = fileSpec-> parID;
- pBlock.dirInfo.ioNamePtr = parentSpec-> name;
- parentSpec-> name[0] = 0;
- pBlock.dirInfo.ioFDirIndex = -1;
-
- result = PBGetCatInfoSync(&pBlock);
-
- if (result == noErr)
- {
- parentSpec-> vRefNum = fileSpec-> vRefNum;
- parentSpec-> parID = pBlock.dirInfo.ioDrParID;
- }
-
- return result;
- }
-
-
- const Int32 kPictFileHeaderSize = 512;
-
- #pragma options align=mac68k
-
- typedef struct PICT2Xheader {
- short version;
- short reserved;
- Fixed hRes;
- Fixed vRes;
- Rect srcRect;
- long reserved2;
- } PICT2Xheader;
-
- #pragma options align=reset
-
- /* ReadPictFrame
-
- Read a pict's rectangle.
- */
- void ReadPictFrame(
- const FSSpec &inPictSpec,
- Rect &outPictRect)
- {
- LFile pictFile(inPictSpec);
-
- pictFile.OpenDataFork(fsRdPerm); // LFile will close the file upon failure
-
- // picture begins past the header
- OSErr result = ::SetFPos(pictFile.GetDataForkRefNum(), fsFromStart, kPictFileHeaderSize);
- ThrowIfOSErr_(result);
-
- // read a PICT2Xheader structure at 16 bytes into the pict
- char pict[sizeof (PICT2Xheader) + 16];
- Int32 count = sizeof (PICT2Xheader) + 16;
- result = ::FSRead(pictFile.GetDataForkRefNum(), &count, &pict);
- ThrowIfOSErr_(result);
-
- PICT2Xheader *pic2XHeader;
- pic2XHeader = (PICT2Xheader *)&(((Ptr)(pict))[16]);
- if (pic2XHeader->version == -2)
- { // extended type 2
- outPictRect = pic2XHeader->srcRect;
- }
- else
- outPictRect = ((Picture *)pict)->picFrame;
-
- pictFile.CloseDataFork();
- }
-
-
- void FixedToStr(
- Fixed inFixValue,
- Str255 outStr)
- {
- // convert to double_t, then use the dec routines
- double_t value = Fix2X(inFixValue);
- decform f;
- f.style = FIXEDDECIMAL;
- f.digits = 1;
- decimal dec;
- num2dec(&f, value, &dec);
- dec2str(&f, &dec, (char *)outStr);
- c2pstr((char *)outStr);
-
- // alternate method using the std C lib
- //sprintf((char *)outStr, "%.1lf", value);
- //c2pstr((char *)outStr);
- }
-
-
- Fixed StrToFixed(
- StringPtr str)
- {
- Fixed theNum;
- long lower,upper;
- short len,i,j, decPoint;
- float fraction;
- Boolean neg;
-
- len = str[0];
-
- for (i=1; i<= len; i++)
- if (str[i] == '.')
- break;
- // No decimal point
- if (i >= len)
- {
- StringToNum(str, &theNum);
- return (theNum << 16);
- }
-
- // Make into two strings
- decPoint = i;
- str[0] = i-1;
- str[decPoint] = len-i;
-
- StringToNum((StringPtr) str, &upper);
- if ((neg = (int)(upper < 0)) != 0)
- upper = - upper;
- StringToNum((StringPtr) str+decPoint, &lower);
-
- fraction = lower;
- for (j = 1; j <= (len-i) ; j++)
- fraction = fraction / 10;
-
- lower = fraction * 0x10000;
-
- // Restore orig string
- str[0] = len;
- str[decPoint] = '.';
-
- return ((neg?-1:1)*((upper << 16) + lower));
- }
-
-
- /* FindCodecName
-
- Search the list of codecs for a name describing the passed codec.
- */
- Boolean FindCodecName(
- StringPtr outName,
- CodecType inCodec)
- {
- Boolean found = false;
-
- CodecNameSpecListPtr cnsp;
- OSErr result = ::GetCodecNameList(&cnsp, 1);
- if (result == noErr)
- {
- for (Int32 i = 0; i < cnsp->count; i++)
- {
- if (cnsp->list[i].cType == inCodec)
- {
- found = true; // yay
- CopyPStr(cnsp->list[i].typeName, outName);
- break;
- }
- }
-
- ::DisposeCodecNameList(cnsp);
- }
-
- return found;
- }
-
-
- /* SetCompressionText
-
- Set the passed pane's descriptor to text describing the passed image compression
- settings.
- */
- void SetCompressionText(
- LPane *inPane,
- CodecType inCodec,
- CodecQ inSpatialQuality)
- {
- if (inPane != nil)
- {
- // attempt to find a name for the current codec
- Str255 str;
- if (!FindCodecName(str, inCodec))
- {
- // put something in the string, however cryptic
- str[0] = 7;
- str[1] = '\'';
- *(OSType *)&str[2] = inCodec;
- str[6] = '\'';
- str[7] = ' ';
- }
- else
- str[++str[0]] = ' ';
-
- // create a description of the compression quality
- Str255 qstr;
- if (inSpatialQuality >= codecLosslessQuality)
- CopyPStr("\pLossless", qstr);
- else if (inSpatialQuality >= codecMaxQuality)
- CopyPStr("\pMaximum", qstr);
- else if (inSpatialQuality >= codecHighQuality)
- CopyPStr("\pHigh", qstr);
- else if (inSpatialQuality >= codecNormalQuality)
- CopyPStr("\pNormal", qstr);
- else if (inSpatialQuality > codecMinQuality)
- CopyPStr("\pLow", qstr);
- else
- CopyPStr("\pMinimum", qstr);
- ConcatPStr(str, qstr);
-
- ConcatPStr(str, "\p (");
- ::NumToString((((((float)inSpatialQuality)+.5) / 1024.0) * 100), qstr);
- ConcatPStr(str, qstr);
- ConcatPStr(str, "\p)");
-
- inPane->SetDescriptor(str);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-